import datetime
import time
# from datetime import time
from rest_framework import status
from rest_framework.permissions import AllowAny
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import User, ThirdParty
from .ser import Third
from utils.tooljwt import myjwt
from utils.sendmes import send_message
from utils.myredis import myredis
from utils.BDapi import bdapi
import redis
from django.utils import timezone
import json
from .ser import UserSer
import random
from .third import fact
# from .third import factory
import requests
from django.http import HttpResponseRedirect, JsonResponse
from django.conf import settings
from django.views import View
from qiniu import Auth
from urllib.parse import quote

# from .third import ThirdPartyLoginFactory


class UserView(APIView):
    permission_classes = [AllowAny]

    def get(self, request):
        user = request.query_params.get('userid')
        if user:
            users = User.objects.filter(id=user).first()
            user = UserSer(users).data
            print(user)
            return Response({"user": user})
        else:
            return Response({"code": 400, "msg": "查询失败"})


class SendCode(APIView):
    # permission_classes = [AllowAny]

    def generate_code(self):
        """生成随机验证码"""
        return str(random.randint(1000, 9999))

    def send_code(self, phone, code):
        """发送验证码到手机"""
        res = send_message(phone, code, 60)
        return json.loads(res)

    def verify_code(self, phone, code):
        """验证用户输入的验证码"""
        stored_code = myredis.get_str(phone)
        return stored_code == code if stored_code else False

    def get(self, request, *args, **kwargs):
        phone = request.query_params.get('phone')
        if not phone:
            return Response({'msg': '手机号不能为空'}, status=status.HTTP_400_BAD_REQUEST)
        code = self.generate_code()
        myredis.set_time_str(phone, code, 60)  # 使用手机号作为key
        return Response({'msg': '数字验证码发送成功', 'code': code})

    def post(self, request):
        phone = request.data.get('phone')
        code = request.data.get('code')

        if not phone or not code:
            return Response({'msg': '手机号和验证码不能为空'}, status=status.HTTP_400_BAD_REQUEST)

        if self.verify_code(phone, code):
            # 生成新的随机验证码并发送
            new_code = self.generate_code()
            send_result = self.send_code(phone, new_code)
            if send_result["statusCode"] == "000000":
                myredis.set_time_str(phone, new_code, 60)  # 设置验证码有效期为60秒
                return Response({'code': 200, 'msg': '验证码发送成功', 'codes': new_code})
            else:
                return Response({'msg': send_result['statusMsg']}, status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response({'msg': '验证码错误'}, status=status.HTTP_400_BAD_REQUEST)


class LoginView(APIView):
    # permission_classes = [AllowAny]

    def post(self, request):
        phone = request.data.get('phone')
        code = request.data.get('code')
        if myredis.is_exist(phone):
            if myredis.get_str(phone) == code:
                user = User.objects.filter(phone=phone).first()
                if user:
                    token = myjwt.jwt_encode({'id': user.id, 'phone': phone,
                                              'exp': int(time.time()) + 3600})
                    retoken = myjwt.jwt_encode({'id': user.id, 'phone': phone,
                                                "exp": int(time.time()) + 7200})
                    return Response({'code': 200, 'msg': '登录成功', 'id': user.id,
                                     'token': token, 'retoken': retoken})
                else:
                    user = User.objects.create(phone=phone)
                    token = myjwt.jwt_encode({'id': user.id, 'phone': phone,
                                              'exp': int(time.time()) + 3600})
                    retoken = myjwt.jwt_encode({'id': user.id, 'phone': phone,
                                                "exp": int(time.time()) + 7200})
                    return Response({'code': 200, 'msg': '登录成功', 'id': user.id,
                                     'token': token, 'retoken': retoken})
            return Response({'code': 400, 'msg': '验证码错误'})


class LogOut(APIView):
    def post(self, request):
        token = request.data.get('token')
        # print(token)
        times = myjwt.jwt_decode(token)
        # print(times)
        time1 = times['exp'] - int(time.time())
        # print(time1)
        myredis.set_str(token, time1)
        return Response({'msg': '退出成功', 'code': 200})


class DingTalkLogin(APIView):
    def get(self, request):
        params = [
            f"redirect_uri={quote('http://127.0.0.1:5173/callback/')}",
            "response_type=code",
            "client_id=dingq04kegs2mhy0ho64",
            "scope=openid",
            "prompt=consent"
        ]
        url = "https://login.dingtalk.com/oauth2/auth?" + ("&".join(params))
        return Response({"url": url})


# 钉钉回调
class DingTalkCallback(APIView):
    def post(self, request):
        authCode = request.query_params.get('code')
        # print(authCode)
        data = {
            "clientId": "dingq04kegs2mhy0ho64",
            "clientSecret": "a_5qWg2FqFrgQnmaa93Wi9cwOgi7L2nXnCwmY22u98orhgX53criMMvpOVy8Ugh3",
            "code": authCode,
            "grantType": "authorization_code"
        }
        resp = requests.post('https://api.dingtalk.com/v1.0/oauth2/userAccessToken', json=data).json()
        # print(resp)
        accessToken = resp.get('accessToken')
        # print(accessToken)
        # 根据accessToken获取用户信息
        headers = {"x-acs-dingtalk-access-token": accessToken}
        # print(headers)
        resp = requests.get('https://api.dingtalk.com/v1.0/contact/users/me', headers=headers).json()
        # phone = resp1.get('phone')
        # uid = resp1.get('openId')
        # data = get_user(phone, uid, 3)
        # return Response({"code": 200, "msg": "登录成功", "id": data.get('id'), "token": data.get('token'),
        #                  "retoken": data.get('retoken')})
        # username = resp.get('username')
        uid = resp.get('openId')
        phone = '13999480579'
        # print(uid, phone)
        sfl = ThirdParty.objects.filter(uid=uid, types=3).first()
        if not sfl:
            # 写入用户表
            # 手机号用户存在直接绑定,不存在注册新用户
            user = User.objects.filter(phone=phone).first()
            # if not user:
            #     userinfo = {
            #         "phone": '13999480579',
            #     }
            #     us = UserSer(data=userinfo)
            #     if us.is_valid():
            #         user = us.save()
            #     else:
            #         return Response({"code": 10001, "msg": (us.errors)})
            # 写入三方登录表
            sfinfo = {
                "types": 3,
                "uid": uid,
                "userid": user.id,
                "token": accessToken
            }
            sfs = Third(data=sfinfo)
            if sfs.is_valid():
                sfs.save()
                # print(sfs)
                # return Response({"code": 200, 'data': sfs.data})
            else:
                # print(sfs.errors)
                return Response({"code": 10001, "msg": sfs.errors})
            #     user = sfl.userid
            #     sfl.token = accessToken
            #     sfl.save()

            # 生成jwt token并返回前端
            payload = {"userid": user.id, "phone": user.phone, "exp": int(time.time()) + 60 * 60 * 2}
            token = myjwt.jwt_encode(payload)
            payload["exp"] = int(time.time() + 60 * 60 * 24 * 2)
            retoken = myjwt.jwt_encode(payload)
            query = [f"userid={payload['userid']}", f"phone={payload['phone']}", f"token={token}",
                     f"refreshToken={retoken}"]
            return HttpResponseRedirect(f'http://localhost:5173/hm/?{"&".join(query)}')


# class DingTalkLoginView(View):
#     def get(self, request):
#         # 构建钉钉授权 URL
#         authorize_url = f"https://login.dingtalk.com/oauth2/auth?redirect_uri={settings.DINGTALK_REDIRECT_URI}&response_type=code&client_id={settings.DINGTALK_APP_KEY}&scope=openid&prompt=consent"
#         return HttpResponseRedirect(authorize_url)
#
#
# class DingTalkCallbackView(View):
#     def get(self, request):
#         # 获取授权码
#         code = request.GET.get('code')
#         if not code:
#             return JsonResponse({'error': 'Missing authorization code'}, status=400)
#
#         # 换取访问令牌
#         token_url = "https://api.dingtalk.com/v1.0/oauth2/userAccessToken"
#         headers = {
#             'Content-Type': 'application/json'
#         }
#         data = {
#             "clientId": settings.DINGTALK_APP_KEY,
#             "clientSecret": settings.DINGTALK_APP_SECRET,
#             "code": code,
#             "grantType": "authorization_code"
#         }
#         response = requests.post(token_url, headers=headers, json=data)
#         token_data = response.json()
#         access_token = token_data.get('accessToken')
#         if not access_token:
#             return JsonResponse({'error': 'Failed to get access token'}, status=400)
#
#         # 获取用户信息
#         user_info_url = f"https://api.dingtalk.com/v1.0/contact/users/me?accessToken={access_token}"
#         user_info_response = requests.get(user_info_url)
#         user_info = user_info_response.json()
#
#         return JsonResponse(user_info)

#
# class DingTalkLoginView(View):
#     def get(self, request):
#         try:
#             # 构建钉钉授权 URL
#             authorize_url = f"https://login.dingtalk.com/oauth2/auth?redirect_uri={settings.DINGTALK_REDIRECT_URI}&response_type=code&client_id={settings.DINGTALK_APP_KEY}&scope=openid&prompt=consent"
#             return HttpResponseRedirect(authorize_url)
#         except Exception:
#             return JsonResponse({'error': 'Failed to generate authorization URL'}, status=500)
#
#
# class DingTalkCallbackView(View):
#     def get(self, request):
#         # 获取授权码
#         code = request.GET.get('code')
#         if not code:
#             return JsonResponse({'error': 'Missing authorization code'}, status=400)
#
#         # 换取访问令牌
#         token_url = "https://api.dingtalk.com/v1.0/oauth2/userAccessToken"
#         headers = {
#             'Content-Type': 'application/json'
#         }
#         data = {
#             "clientId": settings.DINGTALK_APP_KEY,
#             "clientSecret": settings.DINGTALK_APP_SECRET,
#             "code": code,
#             "grantType": "authorization_code"
#         }
#         response = requests.post(token_url, headers=headers, json=data)
#         token_data = response.json()
#         access_token = token_data.get('accessToken')
#         if not access_token:
#             return JsonResponse({'error': 'Failed to get access token'}, status=400)
#
#         # 获取用户信息
#         user_info_url = f"https://api.dingtalk.com/v1.0/contact/users/me?accessToken={access_token}"
#         user_info_response = requests.get(user_info_url)
#         user_info = user_info_response.json()
#
#         # 提取钉钉用户唯一标识，假设为 unionId，按需调整
#         dingtalk_uid = user_info.get('unionId')
#         if not dingtalk_uid:
#             return JsonResponse({'error': 'Missing unionId in user info'}, status=400)
#
#         # 获取当前登录用户
#         user = request.user
#         if not user.is_authenticated:
#             return JsonResponse({'error': 'User is not authenticated'}, status=401)
#
#         # 检查是否已有关联记录
#         try:
#             third_party_record = ThirdParty.objects.filter(types='3', uid=dingtalk_uid).first()
#             if not third_party_record:
#                 # 若不存在关联记录，创建新记录
#                 ThirdParty.objects.create(
#                     types='3',
#                     uid=dingtalk_uid,
#                     userid=user
#                 )
#             else:
#                 # 若存在关联记录，更新用户关联信息
#                 third_party_record.userid = user
#                 third_party_record.save()
#
#         except Exception:
#             return JsonResponse({'error': 'Failed to save third - party association data'}, status=500)
#
#         # 登录成功后跳转到前端首页
#         front_end_home_url = settings.FRONT_END_HOME_URL
#         return HttpResponseRedirect(front_end_home_url)


# class DingTalkLoginView(View):
#     def get(self, request):
#         dingtalk_login = ThirdPartyLoginFactory.create_login_instance('3')
#         authorize_url = dingtalk_login.get_authorize_url()
#         return HttpResponseRedirect(authorize_url)
#
#
# class DingTalkCallbackView(View):
#     def get(self, request):
#         code = request.GET.get('code')
#         if not code:
#             return JsonResponse({'error': 'Missing authorization code'}, status=400)
#
#         dingtalk_login = ThirdPartyLoginFactory.create_login_instance('3')
#         access_token = dingtalk_login.get_access_token(code)
#         if not access_token:
#             return JsonResponse({'error': 'Failed to get access token'}, status=400)
#
#         user_info = dingtalk_login.get_user_info(access_token)
#         dingtalk_uid = user_info.get('unionId')
#         if not dingtalk_uid:
#             return JsonResponse({'error': 'Missing unionId in user info'}, status=400)
#
#         # 这里简单假设用户已经存在，实际应用中可能需要创建新用户
#         user = User.objects.first()  # 可根据实际情况修改获取用户的逻辑
#         dingtalk_login.save_user_info(user_info, user)
#
#         front_end_home_url = settings.FRONT_END_HOME_URL
#         return HttpResponseRedirect(front_end_home_url)


# class DingTalkCallback(APIView):
#     def get(self, request):
#         code=request.query_params.get('type')
#         query = factory.create_factory(code).callback(request)
#         return HttpResponseRedirect(query)


# class QiniuToken(APIView):
#     def get(self,request):
#         qn_token = QnToken()
#         token = qn_token.get(request)
#         print(token)
#         return JsonResponse({"code":200,"token":token})

# APP_KEY = 'dingq04kegs2mhy0ho64'
# APP_SECRET = 'a_5qWg2FqFrgQnmaa93Wi9cwOgi7L2nXnCwmY22u98orhgX53criMMvpOVy8Ugh3'
# CODE = '215e62eb4a653976a34013e1e39b97a0&authCode=215e62eb4a653976a34013e1e39b97a0'
#
# data = {
#     "clientId": APP_KEY,
#     "clientSecret": APP_SECRET,
#     "code": CODE,
#     "grantType": "authorization_code"
# }
#
# url = 'https://api.dingtalk.com/v1.0/oauth2/userAccessToken'
# response = requests.post(url, json=data)
# result = response.json()
#
# if 'accessToken' in result:
#     access_token = result['accessToken']
#     print(f"获取到的用户 AccessToken: {access_token}")
# else:
#     print(f"获取用户 AccessToken 失败: {result}")


# # 调钉钉登录页面
# class DingTalkLogin(APIView):
#     def get(self, request):
#         params = request.query_params.get('params')
#         print(params)
#         class1 = fact.create_factory(params)
#         print(class1)
#         return Response({"code": 200, "url": class1.geturl()})
#
#
# # 钉钉回调
# class DingTalkCallback(APIView):
#     def get(self, request):
#         url = s.callback(request)
#         return Response(url)


class QnToken(APIView):
    def get(self, request):
        # 需要填写你的 Access Key 和 Secret Key
        access_key = 'JCK19oZF_oCjmT0FfkoY3MEqy6KuQGiZVL-Is6Pe'
        secret_key = 'fSOhggdhVPPlhBClJWW2VC2gKvf3UkzuH-yHEI8S'
        # key = 'FnqZeSGEEzk4ZOV0AlOa9Aow0tWi'
        key = ''
        domain = 'http://ssdjkm52e.hn-bkt.clouddn.com/'
        # 构建鉴权对象
        # q = Auth(access_key, secret_key)
        # 要上传的空间
        bucket_name = 'lgmao'
        q = Auth(access_key, secret_key)
        private_url = q.private_download_url(f'{domain}/{key}', expires=3600)
        # print(private_url)
        # 3600为token过期时间，秒为单位。3600等于一小时
        token = q.upload_token(bucket_name)
        return Response({"code": 200, 'token': token})


class BaiDu(APIView):
    def post(self, request):
        picurl = request.query_params.get('picurl')
        # print(picurl, 2222222222222)
        result = bdapi.idcard(picurl)
        # print(result)
        return Response({"code": 200, "msg": "success", "data": result})
